/**
 * SPDX-FileCopyrightText: 2023-2025 Sangfor Technologies Inc.
 * SPDX-License-Identifier: Mulan PSL v2
 */
<template>
    <div class="codestudio-manage-page common-page">
        <div class="codestudio-manage__warp">
            <sf-button-primary size="large" class="codestudio-manage__add" @click="addNote">新增Code Studio
            </sf-button-primary>
            <sf-alert class="alert-item"
                      type="success"
                      :show-default-opr="false"
                      :title="_('CodeStudio超过三天未检测到活跃行为，系统将自动关闭CodeStudio并对资源进行重新调度')"
                      :center="false"/>
            <div class="codestudio-box">
                <div v-for="item in codeStudioList" :key="item.id" class="codestudio-item">
                    <div class="codestudio-item__title">
                        {{ item.name }}
                    </div>
                    <div class="codestudio-item__buttons">
                        <sf-button :default-disabled="!_canOpenServer(item)"
                                   @click="openNote(item)">
                            打开Notebook
                        </sf-button>
                        <sf-button :default-disabled="!_canOpenServer(item) || !_canOpenVSCode(item)"
                                   @click="openVSCode(item)">
                            打开VS Code
                        </sf-button>
                    </div>
                    <el-divider/>
                    <div class="codestudio-item__opt">
                        <div class="opt__left"
                             :disabled="!_canOpenServer(item)"
                             :title="!_canOpenServer(item)?'请先启动codestudio':''"
                             @click="mountDataset(item)">
                            <i class="iconfont iconzairu"/>
                            <span>挂载数据集</span>
                        </div>
                        <div class="opt__endTime flex1">
                            <span class="endTime-label">自动停止剩余时间：</span>
                            <span v-if="item.status === statusMap.status.stopped" class="endTime-text"> - </span>
                            <span v-else class="endTime-text">{{ item.lastActive | dataDiff }}</span>
                            <i class="iconfont iconsip-refresh refresh" style="cursor: pointer;margin-left: 8px;"
                               @click="reloadTime(item)"></i>
                        </div>
                        <div class="opt__trends flex1"
                             :disabled="!_canOpenServer(item)"
                             @click="_showTrend(item)">
                            <i class="iconfont iconrise" style="cursor: pointer;margin-right: 8px;"/>
                            <span class="trends-label">资源趋势监控</span>
                        </div>
                        <div class="opt__status flex1">
                            <span class="status-label">状态：</span>
                            <span :class="statusMap.cls[item.status]" class="status-text">
                                <i v-if="statusMap.icon[item.status]!==''"
                                   class="iconfont"
                                   :class="statusMap.icon[item.status]"></i>
                                <span>{{ statusMap.text[item.status] }}</span>
                            </span>
                        </div>
                        <div class="opt__link">
                            <span class="link-btn"
                                  @click="_openOperationMenu($event, item)">
                                <lang>更多操作</lang>
                            </span>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <sf-menu ref="operationMenu" anchor="bottom" style="width: 124px; border-radius: 4px">
            <sf-menu-item
                v-if="_canStopServer(recordData)"
                style="display: flex"
                @click="_stopNote(recordData)">
                <lang>停止</lang>
            </sf-menu-item>
            <sf-menu-item
                v-else
                style="display: flex"
                :default-disabled="!_canStartServer(recordData)"
                @click="_startNote(recordData)">
                <lang>启动</lang>
            </sf-menu-item>
            <sf-menu-item
                style="display: flex"
                :default-disabled="!_showEditBtn(recordData)"
                @click="editNote(recordData)">
                <lang>编辑</lang>
            </sf-menu-item>
            <sf-menu-item
                style="display: flex"
                :default-disabled="!_canDeleteServer(recordData)"
                @click="_deleteNote(recordData)">
                <lang>删除</lang>
            </sf-menu-item>
            <sf-menu-item
                style="display: flex"
                @click="_openNoteDrawer(recordData)">
                <lang>查看</lang>
            </sf-menu-item>
            <sf-menu-item
                style="display: flex"
                size="small"
                :default-disabled="!_canOpenServer(recordData)"
                @click="_addImage(recordData)">
                <lang>保存镜像</lang>
            </sf-menu-item>
            <sf-menu-item
                style="display: flex"
                size="small"
                :default-disabled="!_canOpenServer(recordData)"
                @click="_ConfigSSH(recordData)">
                <lang>远程开发</lang>
            </sf-menu-item>
        </sf-menu>
        <sf-drawer
            :title="_('查看Code Studio')"
            :visible.sync="isShowDrawer"
            size="450px"
            destroy-on-close
            :direction="direction">
            <div class="preview-detail__container">
                <sf-tab-panel
                    ref="optionsTabpanel"
                    size="large"
                    :tab-width="48"
                    :keep-alive="false"
                    :title-hide="true">
                    <sf-tab-item :title="_('查看详情')">
                        <read-server-form :recordData="recordData"></read-server-form>
                    </sf-tab-item>
                    <sf-tab-item :default-disabled="_canEditServer(recordData) || logSearchStatus"
                                 :title="_('查看日志')">
                        <preview-log :log-list="logList"></preview-log>
                    </sf-tab-item>
                </sf-tab-panel>
            </div>
        </sf-drawer>
    </div>
</template>

<style lang="less" scoped>
.codestudio-manage-page {
    height: calc(100% - 30px);
    background: #fff;
    
    .codestudio-manage__warp {
        height: 100%;
        width: 100%;
        
        .codestudio-manage__add {
            margin-top: 10px;
            height: 36px;
            width: 141px;
            padding: 0 16px;
            font-size: 14px;
            
            /deep/ .sfv-btn-text {
                display: block;
                width: 104%;
            }
        }
        
        .alert-item {
            margin-top: 8px;
            width: 1060px;
            //margin-bottom: 12px;
            background-color: #f2fcf9;
            color: #156AD9;
        }
        
        .codestudio-box {
            margin-top: 8px;
            height: calc(100% - 124px);
            overflow: auto;
            
            .codestudio-item {
                width: 1060px;
                height: 138px;
                border-radius: 6px;
                border-left: 8px solid #166FE2;
                background: #F5F7FA;
                padding: 16px 24px 8px 24px;
                
                .el-divider {
                    margin: 12px 0 10px 0;
                }
                
                &__title {
                    height: 24px;
                    font-size: 16px;
                    line-height: 24px;
                    color: #3D3D3D;
                }
                
                &__buttons {
                    margin-top: 16px;
                    
                    .sfv-btn {
                        height: 28px;
                        
                        & + .sfv-btn {
                            margin-left: 3px;
                        }
                    }
                }
                
                &__opt {
                    display: flex;
                    justify-content: space-between;
                    
                    .flex1 {
                        flex: 1;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                    }
                    
                    .opt__left {
                        cursor: pointer;
                        font-size: 14px;
                        line-height: 22px;
                        height: 22px;
                        color: #1770E6;
                        margin-right: 110px;
                        
                        &[disabled] {
                            cursor: not-allowed;
                            color: #999999;
                        }
                    }
                    
                    .opt__endTime {
                        justify-content: flex-start;
                        
                        .endTime-label {
                            font-size: 14px;
                            line-height: 22px;
                            color: #86909C;
                        }
                        
                        .endTime-text {
                            height: 18px;
                            font-size: 12px;
                            color: #86909C;
                        }
                    }
                    
                    .opt__trends {
                        color: #1770E6;
                        cursor: pointer;
                        font-size: 14px;
                        
                        &[disabled] {
                            cursor: not-allowed;
                            color: #999999;
                        }
                    }
                    
                    .opt__status {
                        display: flex;
                        
                        .status-label {
                            height: 22px;
                            font-size: 14px;
                            line-height: 22px;
                            color: #86909C;
                        }
                        
                        .status-text {
                            width: 88px;
                            height: 22px;
                            border-radius: 12px;
                            display: inline-flex;
                            align-items: center;
                            justify-content: center;
                            
                            i {
                                font-size: 12px;
                                margin-right: 8px;
                            }
                        }
                    }
                    
                    .opt__link {
                        height: 22px;
                        font-size: 14px;
                        line-height: 22px;
                    }
                }
                
                & + .codestudio-item {
                    margin-top: 20px;
                }
            }
        }
        
        .project-manage__toolbar {
            margin-top: 20px;
            margin-bottom: 30px;
            
            .add-btn {
                width: 107px;
                
                .add-btn-icon {
                    font-size: 6px;
                }
                
                &.sfv-btn {
                    background-color: #212121;
                    color: white;
                    margin-right: 10px;
                    height: 38px;
                }
            }
            
            .refresh-btn {
                width: 107px;
                
                &.sfv-btn {
                    border: 1px solid #CCCFD9;
                    height: 38px;
                }
            }
        }
        
        .sperator {
            color: #4677c6;
            margin-left: -5px;
            margin-right: 4px;
        }
        
        .disabled {
            color: #bbb;
        }
        
    }
    
    /deep/ .sfv-toolbar_inner {
        padding: 8px 0px !important
    }
    
    /deep/ .sfv-grid .sfv-table .sfv-table_header {
        background: #edf3fe;
        border-top: 1px solid #edf3fe;
        border-bottom: 1px solid #edf3fe;
        height: 40px;
        line-height: 40px;
    }
    
    /deep/ .sfv-table_row.sfv-table_row-selected {
        background-color: #f9f9f9;
    }
    
    /deep/ .sfv-table_row:hover {
        background-color: #f9f9f9;
    }
}

/deep/ .sfv-menu_list {
    text-align: center !important;
}

/deep/ .sf-drawer__header {
    font-weight: bold;
    
    .sfv-tabpanel .sfv-tabpanel_header .sfv-tabpanel_item:hover {
        background-color: #fff;
    }
}
</style>

<style lang="less">
.mount-dataset-modal, .resource-trend-modal {
    background-color: #ebedf0;
    
    .sfv-modal_header {
        background-color: #ebedf0;
    }
    
    .sfv-modal_body {
        height: calc(100% - 112px);
        
        .sfv-modal_form {
            height: 100%;
            
            .sfv-modal_form-cxt {
                height: 100%;
            }
        }
    }
    
    .sfv-modal_footer {
        background-color: #ebedf0;
    }
    
}
</style>

<script>

import urlAdapter from 'src/home/mod_common/notebooks_url_adapter';
import deployUrlAdapter from 'src/home/mod_common/deploy_url_adapter';
import {dataDiff} from 'src/util/time';
import IntervalTask from 'src/util/interval_task';
import store from 'src/vuex/store';

let userID = store.state.userId;

const PAGE_COUNT = 2000;
const NOTEBOOKS_URL = {
    get: urlAdapter(`users/${userID}/notebooks`),
    post: urlAdapter(`users/${userID}/notebooks`),
    patch: urlAdapter(`users/${userID}/notebooks`),
    getPVC: urlAdapter(`users/${userID}/pvcs`),
    stop: urlAdapter('notebooks'),
    start: urlAdapter('notebooks'),
    edit: urlAdapter('notebooks'),
    delete: urlAdapter('notebooks'),
    getLog: urlAdapter('notebooks')
};

const IMAGE_URLS = {
    get: deployUrlAdapter(`users/${userID}/images`),
    post: deployUrlAdapter(`users/${userID}/commitimage`)
};

// codestudio 的状态映射
import {NOTE_STATUS_MAP} from 'src/home/mod_common/const/server';
import addServerForm from './components/add_server_form.vue';

import readServerForm from './components/read_server_form.vue';

import addImageForm from 'src/home/mod_cluster/common/common_form/add_image_form.vue';
import PreviewLog from 'src/components/preview_log.vue';
import authUrlAdapter from 'src/home/mod_common/auth_url_adapter';
import {setStorage} from 'src/util/local_storage';
import stopConfirmModal from './components/stop_confirm_modal';
import mountDatasetModal from './components/mount_dataset_modal';
import resourceTrendModal from './components/resource_trend_modal/index.vue';
import configSSH from './components/config_ssh';
import {POINT_URL, burialPointParams} from "src/util/burialPoint";

export default {
    filters: {
        dataDiff,
    },
    components: {
        readServerForm,
        PreviewLog
    },
    data() {
        return {
            codeStudioList: [],
            searchParams: {
                keyword: '',
                pageSize: PAGE_COUNT,
                pageNum: 0
            },
            pvcList: [],
            remainSourceData: {},
            isShowDrawer: false,
            direction: 'rtl',
            recordData: {},
            logList: [],
            logSearchStatus: false
        };
    },
    
    computed: {
        statusMap() {
            return NOTE_STATUS_MAP;
        },
        
    },
    
    mounted() {
        this._createIntervalTask();
        this.getResource();
        this.getPvcList();
    },
    
    methods: {
        // 刷新剩余停止时间
        async reloadTime(item) {
            await this.$ajax.get('/dataset-mount/api/v1/ide/flush', {
                id: item.id
            })
            await this.refreshGrid();
        },
        
        _createTrendModal() {
            return this.$modal(resourceTrendModal, {
                autoDestroy: true,
                cls: 'resource-trend-modal',
            });
        },
        _showTrend(item) {
            if (item.status !== this.statusMap.status.running) {
                return;
            }
            let formWin = this._createTrendModal();
            formWin.open({
                title: _('资源利用详情'),
                width: 960,
                height: 810,
                buttons: [
                    {
                        cls: 'sfv-btn',
                        text: _('关闭'),
                        actionName: 'cancel'
                    }
                ],
                data: {
                    id: item.id
                }
                
            })
        },
        _createMountDatasetModal() {
            return this.$modal(mountDatasetModal, {
                autoDestroy: true,
                cls: 'mount-dataset-modal',
                
            });
        },
        mountDataset(item) {
            if (item.status !== this.statusMap.status.running) {
                return;
            }
            let formWin = this._createMountDatasetModal();
            formWin.open({
                title: _('挂载数据集'),
                width: 960,
                height: 854,
                buttons: [
                    {
                        cls: 'sfv-btn',
                        text: _('关闭'),
                        actionName: 'cancel'
                    }
                ],
                data: {
                    url: item.url
                }
            })
        },
        
        async getPvcList() {
            let jsonData = await this.$ajax.get(NOTEBOOKS_URL.getPVC);
            let {success, msg, data} = jsonData;
            if (!success) {
                this.$showErr(msg || _('加载数据失败'));
                return;
            }
            this.pvcList = data.list;
        },
        async getResource() {
            this.$mask();
            const GET_RESOURCE_URL = authUrlAdapter(`user/${userID}/resource`);
            let jsonData = await this.$ajax.get(GET_RESOURCE_URL);
            this.$unmask();
            let {success, msg, data} = jsonData;
            this.remainSourceData = data;
            if (!success) {
                return this.$showErr(msg || _('删除失败'));
            }
        },
        
        // 查看日志
        _createPreviewLogForm() {
            if (!this.previewLogForm) {
                this.previewLogForm = this.$modal(PreviewLog, {
                    autoDestory: true
                });
            }
            return this.previewLogForm;
        },
        
        // 新增镜像弹窗
        _createImageFormWin() {
            if (!this.imageFormWin) {
                this.imageFormWin = this.$modal(addImageForm, {
                    autoDestory: true
                });
            }
            return this.imageFormWin;
        },
        
        // 新增镜像
        _addImage(record) {
            this.$ajax.post(POINT_URL, burialPointParams('save_image', record.id))
            this._createImageFormWin();
            this.imageFormWin.formRoot.refreshCardInfo();
            this.imageFormWin.open({
                reset: true,
                title: _('保存为镜像'),
                data: {
                    showDefaultAddress: false
                },
                submit: () => {
                    let ajaxParams = this.imageFormWin.formRoot.getJsonValue();
                    ajaxParams.notebookName = record.name;
                    ajaxParams.projectId = record.projectId;
                    this.ajaxSubmitImageInfo(ajaxParams, this.imageFormWin);
                }
            });
        },
        
        
        // 配置SSH
        async _ConfigSSH(record) {
            this.$mask()
            const {success, data, msg} = await this.$ajax.get('/helper/api/v1/ssh/enable', {
                namespace: record.userID,
                codeStudio: record.url
            })
            this.$unmask()
            if (!success) {
                this.$showErr(msg)
                return;
            }
            const sshModal = this.$modal(configSSH, {
                autoDestory: true
            });
            sshModal.open({
                title: _('远程开发'),
                buttons: [{
                    actionName: 'cancel',
                    text: _('关闭')
                }],
                data: {
                    data: data
                }
            })
            
        },
        // 新增/编辑算法的卡片信息
        async ajaxSubmitImageInfo(params, formWin) {
            formWin.$mask();
            const ADD_TYPE_URL = `${IMAGE_URLS.post}`;
            let jsonData = await this.$ajax.post(ADD_TYPE_URL, params);
            formWin.$unmask();
            let {success, msg} = jsonData;
            if (!success) {
                return this.$showErr(msg || _('保存失败'));
            }
            this.$ok(_('保存成功'));
            formWin.hide();
            
            await this.refreshGrid();
        },
        
        _startSearch() {
            this.refreshGrid();
        },
        
        _openNoteDrawer(record) {
            let vm = this;
            vm.isShowDrawer = true;
            vm.recordData = record;
            vm._previewLog(record);
        },
        
        _stopNote(record) {
            // 当为失败状态，直接停止不展示弹窗
            
            if (record.status === NOTE_STATUS_MAP.status.failed) {
                this.ajaxStopNote(record);
            } else {
                this._showStopModal(record);
            }
        },
        
        _showStopModal(record) {
            let item = record;
            let params = {};
            if (item) {
                params.id = item.id;
            }
            setStorage('recordName', record.name);
            this.$confirm({
                title: _('提示'),
                msg: stopConfirmModal,
                props:{
                    projectId: record.projectId
                },
                icon: '',
                width: 500,
                autoClose: true,
                callback: actionName => {
                    if (actionName === 'submit') {
                        this.ajaxStopNote(record);
                    }
                }
            });
        },
        
        async _previewLog(record) {
            let vm = this;
            vm.logSearchStatus = false;
            const LOGURL = `${NOTEBOOKS_URL.getLog}/${record.id}/logs`;
            let jsonData = await this.$ajax.get(LOGURL);
            let {success, data} = jsonData;
            if (!success) {
                vm.logSearchStatus = true;
                return this.$showErr(_('查看日志失败，请稍后'));
            }
            vm.logList = data && data.split(/\n/);
        },
        
        async ajaxStopNote(record) {
            this.$ajax.get('/helper/api/v1/datasets/clear', {
                id: record.id,
                type: "save"
            })
            const STOP_NOTE_URL = `${NOTEBOOKS_URL.stop}/${record.id}/stop`;
            let jsonData = await this.$ajax.patch(STOP_NOTE_URL);
            let {success, msg} = jsonData;
            if (!success) {
                this.$showErr(msg || _('加载数据失败'));
                return;
            }
            this.$ok(_('{0}服务已停止', record.name));
            await this.getResource();
            this.refreshGrid();
        },
        
        async _startNote(record) {
            const START_NOTE_URL = `${NOTEBOOKS_URL.start}/${record.id}/start`;
            let jsonData = await this.$ajax.patch(START_NOTE_URL);
            let {success, msg} = jsonData;
            if (!success) {
                this.$showErr(msg || _('加载数据失败'));
                return;
            }
            this.refreshGrid();
        },
        
        // 打开notebooks服务
        async openNote(record) {
            setStorage('volumeName', record.volumeName);
            let query = window.location.search;
            const START_SERVER_URL = `${record.url}${query}`;
            window.open(START_SERVER_URL, '_blank');
            await this.$ajax.post(POINT_URL, burialPointParams('open_notebook', record.id))
        },
        
        async openVSCode(record) {
            let query = window.location.search;
            const START_SERVER_URL = `${record.vscodeUrl}${query}`;
            window.open(START_SERVER_URL, '_blank');
            await this.$ajax.post(POINT_URL, burialPointParams('open_vscode', record.id))
        },
        
        // 新增服务
        _createAddServerForm() {
            return this.$modal(addServerForm, {
                autoDestroy: true
            });
        },
        
        // 编辑note
        editNote(record) {
            let formWin = this._createAddServerForm();
            formWin.formRoot.setJsonValue(record);
            let vm = this;
            formWin.open({
                title: _('编辑Code Studio'),
                data: {
                    pvcList: this.pvcList,
                    isEdit: true,
                    initialVgpu: record.vGpuNum,
                    initialVgpuMemory: record.vGpuMemory,
                    resourceNums: {
                        cpu: vm.remainSourceData.remainedAllocatedCpu + record.cpuNum,
                        memory: vm.remainSourceData.remainedAllocatedMemory + record.memorySize,
                        gpu: vm.remainSourceData.remainedAllocatedGpu + record.gpuNum,
                        workspace: vm.remainSourceData.remainedAllocatedStorage
                    },
                },
                submit: () => {
                    let ajaxParams = formWin.formRoot.getJsonValue();
                    this.ajaxSubmitNoteInfo(ajaxParams, formWin, 'patch');
                }
            });
        },
        
        async addNote() {
            let vm = this;
            let cpuNum = vm.remainSourceData.remainedAllocatedCpu;
            let memoryNum = vm.remainSourceData.remainedAllocatedMemory;
            if (cpuNum < 4 || memoryNum < 4) {
                return this.$showErr(
                    '剩余资源不足，无法创建工作空间，请释放资源或联系管理员。' +
                    '<br/>' +
                    '最低CPU核心配置：4，最低内存配置：4G。'
                );
            }
            let formWin = this._createAddServerForm();
            formWin.formRoot.reset();
            formWin.open({
                title: _('新增Code Studio'),
                reset: true,
                data: {
                    resourceNums: {
                        cpu: cpuNum,
                        memory: memoryNum,
                        gpu: vm.remainSourceData.remainedAllocatedGpu,
                        workspace: vm.remainSourceData.remainedAllocatedStorage
                    },
                    pvcList: this.pvcList,
                    newVolume: this.pvcList.length === 0
                },
                submit: () => {
                    let ajaxParams = formWin.formRoot.getJsonValue();
                    // 新增为0，不让提交
                    if (ajaxParams.newVolume && !ajaxParams.workspace) {
                        return this.$showErr(_('无剩余工作存储空间，请选择已有存储'));
                    }
                    if (!ajaxParams.workspace) {
                        ajaxParams.workspace = 1;
                    }
                    if (!ajaxParams.volumeName) {
                        return this.$showErr(_('未选择工作存储空间，请选择新增或是选择已有存储'));
                    }
                    vm.ajaxSubmitNoteInfo(ajaxParams, formWin);
                }
            });
        },
        
        _deleteNote(record) {
            let item = record;
            let params = {};
            let title = '';
            if (item) {
                params.id = item.id;
                title = item.name;
            }
            this.$confirm({
                title: _('提示'),
                subTitle: _('确定要删除{0}项目吗', title),
                msg: '删除后环境将无法恢复，可将项目保存为镜像后，方便之后继续使用',
                autoClose: true,
                autoDestroy: true,
                callback: actionName => {
                    if (actionName === 'submit') {
                        this.ajaxDeleteNote(params);
                    }
                }
            });
        },
        
        _openOperationMenu(event, item) {
            this.recordData = item;
            this.$refs.operationMenu.showTo(event.target);
        },
        
        async ajaxDeleteNote(params) {
            this.$mask();
            let jsonData = await this.$ajax.delete(`${NOTEBOOKS_URL.delete}/${params.id}`);
            this.$unmask();
            let {success, msg} = jsonData;
            if (!success) {
                return this.$showErr(msg || _('删除失败'));
            }
            this.$ok(_('删除成功'));
            await this.getResource();
            this.refreshGrid();
        },
        
        // 新增/编辑codestudio
        async ajaxSubmitNoteInfo(params, formWin, fetch = 'post') {
            formWin.$mask();
            const ADD_TYPE_URL = `${NOTEBOOKS_URL.post}`;
            const EDIT_NOTE_URL = `${NOTEBOOKS_URL.edit}/${params.id}`;
            const QUERY_URL = fetch === 'post' ? ADD_TYPE_URL : EDIT_NOTE_URL;
            let jsonData = await this.$ajax[fetch](QUERY_URL, params);
            formWin.$unmask();
            let {success, msg} = jsonData;
            if (!success) {
                return this.$showErr(msg || _('保存失败'));
            }
            this.$ok(_('保存成功'));
            formWin.hide();
            await this.getResource();
            await this.refreshGrid();
            this.getPvcList();
        },
        
        _showEditBtn(record) {
            let {
                status,
                name
            } = record;
            if (!name) {
                return false;
            }
            
            return status === NOTE_STATUS_MAP.status.stopped;
        },
        
        _canDeleteServer(record) {
            let {
                status,
                name
            } = record;
            if (!name) {
                return false;
            }
            
            return status === NOTE_STATUS_MAP.status.stopped;
        },
        
        
        _canStopServer(record) {
            let {
                status
            } = record;
            
            // 启用中才显示停止按钮
            return status !== NOTE_STATUS_MAP.status.stopped;
        },
        
        _canStartServer(record) {
            let {
                status
            } = record;
            
            // 已停止才能启动
            return status === NOTE_STATUS_MAP.status.stopped;
        },
        
        _canEditServer(record) {
            let {
                status
            } = record;
            
            // 停止才可以编辑
            return status === NOTE_STATUS_MAP.status.stopped;
        },
        
        _canOpenServer(record) {
            let {
                status
            } = record;
            
            // 已启用才能打开code studio
            return status === NOTE_STATUS_MAP.status.running && record.url;
        },
        
        _canOpenVSCode(record) {
            // vscodeUrl 为空或者null时 按钮禁用
            
            return record.vscodeUrl;
        },
        
        _createIntervalTask() {
            let vm = this;
            this.intervalTask = new IntervalTask({
                fn: () => {
                    vm.refreshGrid().then(() => {
                        vm.intervalTask && vm.intervalTask.next();
                    });
                },
                interval: 10000,
                autoStart: true
            });
        },
        
        async refreshGrid() {
            
            // 因为轮询，暂时删除refreshGrid的mask提示，提示用户体验。
            // this.$mask();
            let jsonData = await this.$ajax.get(NOTEBOOKS_URL.get, this.searchParams);
            
            // this.$unmask();
            let {success, msg, data} = jsonData;
            if (!success) {
                this.$showErr(msg || _('加载数据失败'));
                return;
            }
            this.codeStudioList = data.list;
            
            let startingLength = data.list.filter(item => item.status === 'starting').length;
            
            // 存在启动中这种情况才会定时刷新,不存在loading则可以关掉定时器。
            if (!startingLength) {
                this.intervalTask && this.intervalTask.stop();
            } else {
                this.intervalTask && this.intervalTask.start();
            }
        },
    },
    
    beforeDestroy() {
        if (this.intervalTask) {
            this.intervalTask.stop();
            this.intervalTask = null;
        }
        
    }
    
    
};
</script>
